﻿using Edutainment.Interfaces;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Edutainment
{
    [Serializable()]
    public class SortAlgorithm
    {
        String name;

        protected int _exercises;
        protected int _solvedExercises;
        protected int _exams;
        protected int _solvedExams;
        public int exercises
        {
            get { return _exercises; }
            protected set
            {
                _exercises = value;
                informStatistcObserver();
            }
        }
        public int solvedExercises
        {
            get { return _solvedExercises; }
            protected set
            {
                _solvedExercises = value;
                informStatistcObserver();
            }
        }
        public int exams
        {
            get { return _exams; }
            protected set
            {
                _exams = value;
                informStatistcObserver();
            }
        }
        public int solvedExams
        {
            get { return _solvedExams; }
            protected set
            {
                _solvedExams = value;
                informStatistcObserver();
            }
        }

        public int countOfSteps
        {
            get { return stepList.Count; }
        }

        [NonSerialized]
        private ArrayList updateList;
        [NonSerialized]
        private ISortationInterface _sortationDelegate;
        public ISortationInterface sortationDelegate { get { return _sortationDelegate; } set { _sortationDelegate = value; } }
        private bool isExam;
        private bool inProgress;

        protected ArrayList listToSort;
        protected ArrayList sortedList;
        protected ArrayList stepList;

        public SortAlgorithm(String sortName)
        {
            name = sortName;
            exercises = 0;
            solvedExercises = 0;
            exams = 0;
            solvedExams = 0;
            updateList = new ArrayList();
            listToSort = new ArrayList();
            stepList = new ArrayList();
            inProgress = false;

        }

        public String toString()
        {
            return name;
        }

        public void solve()
        {
            if (inProgress)
            {
                if (isExam)
                    this.solvedExams = solvedExams + 1;
                else
                    this.solvedExercises = solvedExercises + 1;

                inProgress = false;
            }
        }

        public void start()
        {
            if (!inProgress)
            {
                if (isExam)
                    this.exams = exams + 1;
                else
                    this.exercises = exercises + 1;

                inProgress = true;
            }
        }

        public void restart()
        {
            if (inProgress)
            {
                inProgress = false;
            }

        }

        protected void generateListToSort(int count)
        {
            listToSort.Clear();
            Random rnd = new Random(DateTime.Now.Millisecond);

            for (int i = 0; i < count; i++)
            {
                listToSort.Add(rnd.Next(1, 101));
            }

        }

        public void createListToSort(int count, bool exam)
        {
            isExam = exam;
            this.generateListToSort(count); ;
        }

        private void sortForCorrectSteps(ArrayList toSort)
        {

        }

        public ArrayList getListToSort()
        {
            return listToSort;
        }

        public void addObserverForStatisticUpdates(IStatisticInterface sDelegate)
        {
            if (sDelegate != null)
            {
                if (updateList == null)
                    updateList = new ArrayList();

                if (!updateList.Contains(sDelegate))
                    updateList.Add(sDelegate);

                informStatistcObserver();
            }
        }

        public void removeObserverFromStatisticUpdates(IStatisticInterface sDelegate)
        {
            if (updateList.Contains(sDelegate))
            {
                updateList.Remove(sDelegate);
            }
        }

        private void informStatistcObserver()
        {
            if (updateList != null)
            {
                foreach (IStatisticInterface del in updateList)
                {
                    del.updateGui();
                }
            }
        }
    }
}
